package com.slipper.constants;

import com.slipper.exception.NotLoginException;
import com.slipper.util.AESUtil;
import com.slipper.util.JwtUtil;
import com.slipper.util.Tool;
import com.slipper.common.bo.UserDetail;
import com.slipper.core.gson.GsonUtil;
import com.slipper.util.GzipUtil;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Objects;

public class Constants {
    /** 当前时间变量名 */
    public static final String CURRENT_USER_SESSION = "userSessionId";
    public static final String CURRENT_CAPTCHA = "currentCaptcha";
    public static final String CURRENT_DRUID_SESSION = "druid-user";

    /** 是 */
    public static final String YES = "1";
    /** 否 */
    public static final String NO = "0";
    /** 有效 */
    public static final String VALID = "1";

    public static final String ROOT_ID = "0";

    public static final String ORDER_BY_ASC = "升序";
    public static final String ORDER_BY_DESC = "降序";

    /** 子系统变量 */
    public static class Subsystem {
        /** 管理端 */
        public static final String TYPE_MANAGE = "1";
        /** 门户端 */
        public static final String TYPE_PORTAL = "2";
        /** 子系统 */
        public static final String TYPE_SUBSYSTEM = "3";
    }

    /** 数据变量 */
    public static class DataModel {
        /** 库表 */
        public static final String TYPE_TABLE = "1";
        /** 视图 */
        public static final String TYPE_VIEW = "2";
        /** 源表 */
        public static final String TYPE_LOCAL_TABLE = "3";
    }

    /** 数据库类型变量 */
    public static class Database {
        public static final String MYSQL = "mysql";
        public static final String ORACLE = "oracle";
        public static final String POSTGRESQL = "postgresql";
        public static final String SQLSERVER = "sqlserver";
    }

    public static HttpServletRequest getCurrentRequest() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
    }

    public static HttpServletResponse getCurrentResponse() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getResponse();
    }

    /**
     * 设置当前验证码
     */
    public static void setCaptcha(String captcha) {
        if (captcha == null) {
            getCurrentRequest().getSession().removeAttribute(CURRENT_CAPTCHA);
        } else {
            getCurrentRequest().getSession().setAttribute(CURRENT_CAPTCHA, captcha);
        }
    }

    /**
     * 获取当前验证码
     */
    public static String getCaptcha() {
        return (String) getCurrentRequest().getSession().getAttribute(CURRENT_CAPTCHA);
    }

    /**
     * 获取当前验证码并清除验证码
     */
    public static String getAndCleanCaptcha() {
        String captcha = (String) getCurrentRequest().getSession().getAttribute(CURRENT_CAPTCHA);
        getCurrentRequest().getSession().removeAttribute(CURRENT_CAPTCHA);
        return captcha;
    }

    public static void setSessionUser(UserDetail userDetail) {
        setSessionUser(getCurrentRequest().getSession(), userDetail);
    }

    public static void setSessionUser(HttpSession session, UserDetail userDetail) {
        String compress = GzipUtil.compress(GsonUtil.toJson(userDetail));
        session.setAttribute(CURRENT_USER_SESSION, compress);

        // 同步登录druid
        if (userDetail.isSuperAdmin()) {
            session.setAttribute(CURRENT_DRUID_SESSION, userDetail.getEmployee().getId());
        } else {
            session.removeAttribute(CURRENT_DRUID_SESSION);
        }
    }

    public static boolean hasSessionUser(HttpSession session) {
        return Tool.isNotBlank(session.getAttribute(CURRENT_USER_SESSION));
    }

    public static UserDetail getSessionUser(HttpSession session) {
        String json = (String) session.getAttribute(CURRENT_USER_SESSION);
        if (Tool.isNotBlank(json)) {
            return GsonUtil.fromJson(GzipUtil.uncompress(json), UserDetail.class);
        } else {
            return null;
        }
    }

    public static String getCurrentUserId() {
        UserDetail userDetail = getCurrentUser();
        return userDetail == null ? null : userDetail.getEmployeeId();
    }

    public static String getCurrentUserId(boolean required) {
        UserDetail userDetail = getCurrentUser(required);
        return userDetail == null ? null : userDetail.getEmployeeId();
    }

    public static UserDetail getCurrentUser() {
        return getCurrentUser(true);
    }

    public static UserDetail getCurrentUser(boolean required) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) return null;

        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        UserDetail userDetail = getSessionUser(request.getSession());
        if (userDetail == null) {
            String auth = request.getHeader("Authorization");
            String prefix = "Token ";
            if (Tool.isNotBlank(auth) && auth.startsWith(prefix)) {
                String token = auth.substring(prefix.length());
                userDetail = GsonUtil.fromJson(JwtUtil.parserToken(AESUtil.decrypt(token)), UserDetail.class);
            }
        }

        if (userDetail == null && required) {
            throw new NotLoginException();
        }

        return userDetail;
    }
}
